home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / perl5 / Dpkg / Path.pm < prev    next >
Encoding:
Perl POD Document  |  2012-09-17  |  5.4 KB  |  223 lines

  1. # Copyright ┬⌐ 2007 Rapha├½l Hertzog <hertzog@debian.org>
  2. #
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  15.  
  16. package Dpkg::Path;
  17.  
  18. use strict;
  19. use warnings;
  20.  
  21. our $VERSION = "1.01";
  22.  
  23. use base qw(Exporter);
  24. use File::Spec;
  25. use Cwd qw(realpath);
  26. our @EXPORT_OK = qw(get_pkg_root_dir relative_to_pkg_root
  27.             guess_pkg_root_dir check_files_are_the_same
  28.             resolve_symlink canonpath find_command);
  29.  
  30. =encoding utf8
  31.  
  32. =head1 NAME
  33.  
  34. Dpkg::Path - some common path handling functions
  35.  
  36. =head1 DESCRIPTION
  37.  
  38. It provides some functions to handle various path.
  39.  
  40. =head1 METHODS
  41.  
  42. =over 8
  43.  
  44. =item get_pkg_root_dir($file)
  45.  
  46. This function will scan upwards the hierarchy of directory to find out
  47. the directory which contains the "DEBIAN" sub-directory and it will return
  48. its path. This directory is the root directory of a package being built.
  49.  
  50. If no DEBIAN subdirectory is found, it will return undef.
  51.  
  52. =cut
  53.  
  54. sub get_pkg_root_dir($) {
  55.     my $file = shift;
  56.     $file =~ s{/+$}{};
  57.     $file =~ s{/+[^/]+$}{} if not -d $file;
  58.     while ($file) {
  59.     return $file if -d "$file/DEBIAN";
  60.     last if $file !~ m{/};
  61.     $file =~ s{/+[^/]+$}{};
  62.     }
  63.     return undef;
  64. }
  65.  
  66. =item relative_to_pkg_root($file)
  67.  
  68. Returns the filename relative to get_pkg_root_dir($file).
  69.  
  70. =cut
  71.  
  72. sub relative_to_pkg_root($) {
  73.     my $file = shift;
  74.     my $pkg_root = get_pkg_root_dir($file);
  75.     if (defined $pkg_root) {
  76.     $pkg_root .= "/";
  77.     return $file if ($file =~ s/^\Q$pkg_root\E//);
  78.     }
  79.     return undef;
  80. }
  81.  
  82. =item guess_pkg_root_dir($file)
  83.  
  84. This function tries to guess the root directory of the package build tree.
  85. It will first use get_pkg_root_dir(), but it will fallback to a more
  86. imprecise check: namely it will use the parent directory that is a
  87. sub-directory of the debian directory.
  88.  
  89. It can still return undef if a file outside of the debian sub-directory is
  90. provided.
  91.  
  92. =cut
  93.  
  94. sub guess_pkg_root_dir($) {
  95.     my $file = shift;
  96.     my $root = get_pkg_root_dir($file);
  97.     return $root if defined $root;
  98.  
  99.     $file =~ s{/+$}{};
  100.     $file =~ s{/+[^/]+$}{} if not -d $file;
  101.     my $parent = $file;
  102.     while ($file) {
  103.     $parent =~ s{/+[^/]+$}{};
  104.     last if not -d $parent;
  105.     return $file if check_files_are_the_same("debian", $parent);
  106.     $file = $parent;
  107.     last if $file !~ m{/};
  108.     }
  109.     return undef;
  110. }
  111.  
  112. =item check_files_are_the_same($file1, $file2, $resolve_symlink)
  113.  
  114. This function verifies that both files are the same by checking that the device
  115. numbers and the inode numbers returned by stat()/lstat() are the same. If
  116. $resolve_symlink is true then stat() is used, otherwise lstat() is used.
  117.  
  118. =cut
  119.  
  120. sub check_files_are_the_same($$;$) {
  121.     my ($file1, $file2, $resolve_symlink) = @_;
  122.     return 0 if ((! -e $file1) || (! -e $file2));
  123.     my (@stat1, @stat2);
  124.     if ($resolve_symlink) {
  125.         @stat1 = stat($file1);
  126.         @stat2 = stat($file2);
  127.     } else {
  128.         @stat1 = lstat($file1);
  129.         @stat2 = lstat($file2);
  130.     }
  131.     my $result = ($stat1[0] == $stat2[0]) && ($stat1[1] == $stat2[1]);
  132.     return $result;
  133. }
  134.  
  135.  
  136. =item canonpath($file)
  137.  
  138. This function returns a cleaned path. It simplifies double //, and remove
  139. /./ and /../ intelligently. For /../ it simplifies the path only if the
  140. previous element is not a symlink. Thus it should only be used on real
  141. filenames.
  142.  
  143. =cut
  144.  
  145. sub canonpath($) {
  146.     my $path = shift;
  147.     $path = File::Spec->canonpath($path);
  148.     my ($v, $dirs, $file) = File::Spec->splitpath($path);
  149.     my @dirs = File::Spec->splitdir($dirs);
  150.     my @new;
  151.     foreach my $d (@dirs) {
  152.     if ($d eq '..') {
  153.         if (scalar(@new) > 0 and $new[-1] ne "..") {
  154.         next if $new[-1] eq ""; # Root directory has no parent
  155.         my $parent = File::Spec->catpath($v,
  156.             File::Spec->catdir(@new), '');
  157.         if (not -l $parent) {
  158.             pop @new;
  159.         } else {
  160.             push @new, $d;
  161.         }
  162.         } else {
  163.         push @new, $d;
  164.         }
  165.     } else {
  166.         push @new, $d;
  167.     }
  168.     }
  169.     return File::Spec->catpath($v, File::Spec->catdir(@new), $file);
  170. }
  171.  
  172. =item $newpath = resolve_symlink($symlink)
  173.  
  174. Return the filename of the file pointed by the symlink. The new name is
  175. canonicalized by canonpath().
  176.  
  177. =cut
  178.  
  179. sub resolve_symlink($) {
  180.     my $symlink = shift;
  181.     my $content = readlink($symlink);
  182.     return undef unless defined $content;
  183.     if (File::Spec->file_name_is_absolute($content)) {
  184.     return canonpath($content);
  185.     } else {
  186.     my ($link_v, $link_d, $link_f) = File::Spec->splitpath($symlink);
  187.     my ($cont_v, $cont_d, $cont_f) = File::Spec->splitpath($content);
  188.     my $new = File::Spec->catpath($link_v, $link_d . "/" . $cont_d, $cont_f);
  189.     return canonpath($new);
  190.     }
  191. }
  192.  
  193.  
  194. =item my $cmdpath = find_command($command)
  195.  
  196. Return the path of the command if available on an absolute or relative
  197. path or on the $PATH, undef otherwise.
  198.  
  199. =cut
  200.  
  201. sub find_command($) {
  202.     my $cmd = shift;
  203.  
  204.     if ($cmd =~ m{/}) {
  205.     return "$cmd" if -x "$cmd";
  206.     } else {
  207.     foreach my $dir (split(/:/, $ENV{'PATH'})) {
  208.         return "$dir/$cmd" if -x "$dir/$cmd";
  209.     }
  210.     }
  211.     return undef;
  212. }
  213.  
  214. =back
  215.  
  216. =head1 AUTHOR
  217.  
  218. Rapha├½l Hertzog <hertzog@debian.org>.
  219.  
  220. =cut
  221.  
  222. 1;
  223.